#pragma once
#include "google/protobuf/service.h"
#include<string>
#include<functional>
#include<google/protobuf/descriptor.h>
#include<muduo/net/TcpServer.h>
#include<muduo/net/EventLoop.h>
#include<muduo/net/InetAddress.h>
#include<muduo/net/TcpConnection.h>

// 框架提供的专门服务发布rpc服务的网络对象类
class RpcProvider
{
public:
    //这里是框架提供给外部使用的，可以发布rpc方法的函数接口，不能接收具体业务，而这些业务都继承自google::protobuf::Service
    void NotifyService(google::protobuf::Service *service);

    //启动rpc服务节点，开始提供rpc远程网络服务调用
    void Run();

private:
    //关于rpc网络这一块，将tcpserver定义成一个指针，直接使用智能指针

    //组合了EventLoop
    muduo::net::EventLoop m_eventLoop;

    //service服务类型信息，例如Userservice这个服务或者UserFriendList这个服务
    struct ServiceInfo
    {
        google::protobuf::Service *m_service;//保存服务对象，因为服务方法需要使用服务对象来调用
        std::unordered_map<std::string,const google::protobuf::MethodDescriptor*> m_methodMap;//保存服务方法<方法名字，方法描述>
    };
    //存储注册成功的服务对象和其服务方法的所有信息<服务名字，服务信息>
    std::unordered_map<std::string,ServiceInfo> m_serviceMap;
    
    //新的socket连接回调
    void OnConnection(const muduo::net::TcpConnectionPtr&);
    //已建立连接的用户的读写事件的回调
    void OnMessage(const muduo::net::TcpConnectionPtr&, muduo::net::Buffer* ,muduo::Timestamp);

    //Closure的回调操作，用于序列化rpc的响应和网络发送,所以需要Connection参数(有网络)和Message参数(发送的消息)
    void SendRpcResponse(const muduo::net::TcpConnectionPtr& conn,google::protobuf::Message*);
}; 